﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Vparser
{

    public class vMod
    {
        public int ix;
        public string name;
        public vMod mod;
        string op = null;
        uint bp = 0, np = 0;
        uint v1;
        uint v2;
        int nxtprec;
        public valb vp = new valb();
        public vParse pvp;

        public class input
        {
            public string name; 
            public vvbl vbl;  // = new vvbl();
            // char typ; public int fx; public int fy; public List<stk_ty> opL;
            public vParse.output mOut;// public List<valways> edges ;
        };
        public List<input> inputs;

        public List<vParse.output> outputs;

        public class inout
        {
            public string name; public string vtyp; public int bx; public int by;
            public uint val; string nm; public int ix;
        };
        public List<inout> inouts;

        public struct parm
        {
            public string name; public uint val;
        }
        public List<parm> parms;

        //public class vstatement 
        //{
        //    public string vs; public string stype; public int bix; public int eix; public vstatement nxt;
        //}
        //public List<vstatement> sList;

        public class vvbl
        {
            public valb vb = new valb();

            public uint val
            {
                get { return (bwire && opsL != null) ? wval & wmsk : vval & wmsk; }
                set { vval = value & wmsk; }  //(opL != null) ? vb.vv(ref opL, 0, ref i)
            }

            uint wval
            {
                get { return vb.vv(0, opsL[0]); } 
            }

            public List<stk_ty> opL
            {
                get { return opsL; }
                set { opsL = value; }
            }

            public bool edge
            {
                get { return bedge; }
                set {bedge = value; }
            }
            public bool wire
            {
                get { return bwire; }
                set { bwire = value; }
            }

            public uint rhs
            {
                get { return vsu; } // = vp.vv(opL, 0, ref i)&wmsk ; }
                set { vsu = value; }

            }

            public uint lhs
            {
                get { return vval; }
                set { vval = value; }
            }

            uint wmsk = 0xffffffff;
            public uint width
            {
                get { return vwidth; }
                set { vwidth = value; wmsk = 0xffffffff; }
            }
            public string name; public uint vval; int i = 0; //public string typ; 
            public int scn_ix;  List<stk_ty> opsL;
            public List<valways> pe;
            public List<valways> ne;
         //   public List<valways> lvl;
            public List<valways> awL;
            bool bedge;
            bool bwire;
            uint vsu, vwidth = 0xffffffff;
            //uint get_vv()
            //{
            //    return vp.vv( opL, 0, ref i);
            //    //   return 0xffff;
            //}
        }


        public List<vvbl> mvbls;

        public class tgr
        {
            string name; int scn_ix; public int l_ix;
            public uint width
            {
                set { width = value; }
            }
            public uint val
            {
                get { return val; }
            }
            List<valways> alwb;
         public   List<stk_ty> opL;
            public virtual uint rhs()
            {
                return val;
            }
        }

        class dtgr   :  tgr
        {
            valb vp = new valb();
            public override uint rhs()
            {
                return vp.vv(0, opL[0]); 
            }
        }

        public class vwire
        {
            public uint val
            {
                get { return val; } // vv(ref opL, 0, ref l_ix); }

                set { val = value; }
            }
            public string name;// public uint val;  //public string typ; 
            public int scn_ix, l_ix = 0, i;
            public List<stk_ty> opL;  // = new List<stk_ty>();
            public List<valways> pe;
            public List<valways> ne;
            public List<valways> lvl;
            public enum flgs { };
            valb vp = new valb();
            uint get_vv()
            {
                return vp.vv(0, opL[0]);
                //   return 0xffff;
            }
        }
        public List<vwire> vwires;

        //public class vedge
        //{
        //    public vvbl vW; public uint valNxt; public valways va;
        //}
        //public List<vedge> peList;

        //public List<vedge> neList;

        public List<object> vops;
        public struct ops { public List<stk_ty> opL; public vMod.vvbl vr; }
       
        public class valways
        { 
         //   public string typ; public stk_ty orig;
            public vif fif;   // = new vif();
            //  public vif nxtif;
            public List<object> vsL = new List<object>();
            public List<ops> bL;
            public List<ops> nbL;
            public List<vvbl> nbU;
    
        }

        public void simalways( vif nxtif )  //, velse nxtelse)
        {
         //   if (nxtif != null)
     //           simif(nxtif);
       //     else
                //if (bl != null) doba(bl);
                //else if (nbL != null) dobq(nbL);
                //else MessageBox.Show("simalways error");
        }


        public class vif
        {
            public List<stk_ty> condL; //vcond ifcond; //public stk_ty vt; public stk_ty vf;
            public vif fif;
            public velse nxtelse;
            public List<object> vsL;
            public List<ops> bL;
            public List<ops> nbL;
            valb va = new valb();
            int i = 0;
            public void simif(List<vvbl> nbU)  //vif me)
            {
                if (va.vv(0, condL[0]) > 0)
                {
                    if (bL != null && bL.Count > 0)
                    {
                        foreach (ops v in bL)
                        {
                            v.vr.lhs = va.vv(0, v.opL[0]);

                            //Form1 myf1 = Form1.ActiveForm;
                            //myf1.lb2o;
                        }
                    }
                    if (nbL != null && nbL.Count > 0)
                    {
                        foreach (ops v in nbL)
                        {
                            v.vr.rhs = va.vv(0, v.opL[0]);
                            nbU.Add(v.vr);
                        }
                    }
                    if (fif != null && fif.condL != null)
                        fif.simif(nbU);

                }
                    else
                        if (nxtelse != null)  // && fif.condL != null)
                            nxtelse.simelse(nbU);
                }
        }

         //   void simif(List<stk_ty> condL, vif nxtif, velse nif)
         //   {

             //   if ( vv() != 0)
               // {  // if ok
                 //   if (nxtif != null) nxtif.simif();
              //  }
                //else  //  try else
                //    if (nxtelse != null) nxtelse.sim();
                //    else  // no else  do assign
                //        if (bL != null) doba(bL);
                //        else
                //            if (nbL != null) doba(nbL);
                //            else MessageBox.Show("simif error");
                 
          //  }

        public class velse
        {
            public vif fif;
            public List<ops> bL;
            public List<ops> nbL;
            public List<object> vsL;
            valb va = new valb();
            int i = 0;
            public void simelse(List<vMod.vvbl> nbU)
            {
                if (bL != null)
                {
                    foreach (ops v in bL)
                    {
                        v.vr.lhs =  va.vv(0, v.opL[0]);
                    }
                }
                if (nbL != null)
                {
                    foreach (ops v in nbL)
                    {
                        v.vr.rhs = va.vv(0, v.opL[0]);
                        nbU.Add(v.vr);
                    }
                } 
                if (fif != null && fif.condL != null) fif.simif(nbU);
            }

        }

        //public class vba
        //{
        //    public vvbl LHS; public List<stk_ty> opL;
        //}

        public class vbnb
        {
            public vvbl LHS; public vvbl RHS; public List<stk_ty> opL;
        }

        public class vfor { public string vop; public uint op1; public uint op2;}

        public vParse.output get_out(string nm_str, vMod ld, input inSt)
        {
            {
                int dotx;
                string  modnm;
                vMod.vvbl v;
                if ((dotx = nm_str.IndexOf('.')) > 0)
                   modnm = nm_str.Substring(0, dotx);
                    nm_str = nm_str.Substring(dotx + 1);
                if (this.outputs == null) this.outputs = new List<vParse.output>();
                foreach (vParse.output ne in this.outputs)  // see if output was already created
                {
                    if (ne.name == nm_str)  // & ne.dly == (int)uldly & ne.dly_flg == dly_typ)
                    { 
                        return ne;
                    }
                }
                vParse.output nnt = new vParse.output();  //create new output
                //   nnt.ix = vSys.outputs.Count;
                nnt.name = nm_str;
                if(nnt.fout == null) 
                    nnt.fout = new List<input>();
           //     nnt.fout.Add(inSt);
                //   nnt.dly_flg = dly_typ;
                //vMod.vvbl ov = new vMod.vvbl();
                //ov.name = nm_str;
                nnt.vbl = new vvbl();
                nnt.vbl.name = nm_str;
                if (this.mvbls == null) this.mvbls = new List<vvbl>();
                this.mvbls.Add(nnt.vbl);
                this.outputs.Add(nnt);
                return nnt;
 //               vedge x = new vedge();
//                x.vbl  = nnt. ;
            }
        }
    }


    public class vBuild
    {
        public List<vMod> modList;
        //public List<vMod.vedge> peList;
        //public List<vMod.vedge> neList;

        public List<vParse.output> outputs;

        public List<vMod.vvbl> mvbls;

        public List<vMod.valways> always;

        public List<Object> sList = new List<Object>();

        public vParse.output get_out(string nm_str, vMod mLd, vMod.input inSt)
        {
            {
                if (this.outputs == null) this.outputs = new List<vParse.output>();
                foreach (vParse.output ne in this.outputs)  // see if output was already created
                {
                    if (ne.name == nm_str)
                        return ne;
                }
                vParse.output nnt = new vParse.output();  //create new output
                nnt.name = nm_str;
                nnt.fout = new List<vMod.input>();
           //     nnt.opL = new List<stk_ty>();
                nnt.name = nm_str;
                if(inSt != null)
                nnt.fout.Add(inSt);
                vMod.vvbl v = new vMod.vvbl();
                v.name = nm_str;
                this.mvbls.Add(v);
                nnt.vbl = v;
                
                this.outputs.Add(nnt);
                return nnt;
            }
        }
    }
}